<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>ajax瀑布流--浮动布局</title>
<style>
*{
	padding:0px;
	margin:0px;
}
ul{
	list-style: none;
}

#div1{
	width: 785px;
	height: auto;
	margin: 20px auto; 
}
ul{
	width: 225px;
	margin: 5px;
	float: left;
}
</style>
<link rel="stylesheet" type="text/css" href="../../../css/article_base.css" />
<script type="text/javascript" src="demo.js"></script>
</head>
<body>

<p class="title">概述 ajax瀑布流--浮动布局</p>
布局方法：共3个ul，每个ul代表一列，ul内的每个li代表一个图文信息。所有ul全部左浮动<br />
某个ul的最后一个li出现在可视区后(此例中就是最右边的000图片) 就开始ajax请求一批新数据 <br />
请求得到json数据后生成li 轮流给3个ul内部添加li 实现瀑布流展示<br />
具体ajax请求可用firebug网络XHR查看 具体代码实现见底部js代码

<p class="title">DEMO演示 ajax瀑布流--浮动布局 共10批数据</p>

<div id="div1">
	<ul>
		<li>
			<img src="img/1.jpg" />
			<p>1111111111</p>
		</li>
		<li>
			<img src="img/2.jpg" />
			<p>2222222222</p>
		</li>
		<li>
			<img src="img/3.jpg" />
			<p>3333333333</p>
		</li>
	</ul>
	<ul>
		<li>
			<img src="img/4.jpg" />
			<p>4444444444</p>
		</li>
		<li>
			<img src="img/5.jpg" />
			<p>5555555555</p>
		</li>
		<li>
			<img src="img/6.jpg" />
			<p>6666666666</p>
		</li>
		<li>
			<img src="img/9.jpg" />
			<p>999999999</p>
		</li>
	</ul>
	<ul>
		<li>
			<img src="img/7.jpg" />
			<p>777777777</p>
		</li>
		<li>
			<img src="img/8.jpg" />
			<p>888888888</p>
		</li>
		<li>
			<img src="img/9.jpg" />
			<p>000000000</p>
		</li>
	</ul>
</div>


<p class="title" style="clear:both">js代码</p>
<pre>
//ajax瀑布流--浮动布局
window.onload = function(){
	var oDiv1 = document.getElementById('div1');
	var aUl = oDiv1.getElementsByTagName('ul');
	var flag = true;
	var batchNum = 1;

	//鼠标滚轮事件
	window.onscroll = function(){
		var viewHeight = getInner().height;
		var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;

		for(var i=0; i&ltaUl.length; i++){
			var aLi = aUl[i].getElementsByTagName('li');	
			var oLastLi = aLi[aLi.length - 1];				
			//某个ul的最后一个li出现在可视区后 就开始ajax请求新数据
			if((viewHeight + scrollTop > posTop(oLastLi)) && flag){	
				//flag开关的作用！！！！！关键点！！！！！
				//onscroll会瞬间触发多次 此时的(viewHeight + scrollTop > posTop(oLastLi))还没计算完成
				//所以只有马上改变flag才能阻止瞬间多次触发
				//所以onscroll第一次触发后flag就为flase 保证瞬间只一次ajax请求
				flag = false;

				//请求第batchNum批数据
				ajax('data.php?batch='+batchNum, function(str){
					//注意在将json字符串解析为json对象的时候 必须'('+str+')'
					//如果不加那就是eval({xxx}) eval会把{}当做语句块解析 然后报错
					//如果加了eval(({xxx})) eval就会把()内部的json解析成一个对象
					var json = eval('('+str+')');

					//遍历出所有数据 生成li
					for(var i in json.list){
						for(var j in json.list[i].src){
							var oLi = document.createElement('li');
							oLi.innerHTML = '&ltimg src="'+ json.list[i].src[j] +'"/>&ltp>'+ json.list[i].title[j] +'&lt/p>';
							aUl[i].appendChild(oLi);
						}
					}

					//当次ajax请求后 再打开触发onscroll的开关 以备触发下一批次的ajax请求
					//此时已是若干秒后 (viewHeight+scrollTop>posTop(oLastLi))计算已完成 能正确用于if判断了
					if(json.batch &lt 10){	//第10批是最后一批 之后不再开启onscroll开关
						flag = true;
					}

					//ajax请求完毕后 批次数累加1 为下一批次数据准备
					batchNum++;
				});
			}
		}
	}
	
}


//兼容 让IE6 7 8的offsetTop也是相对窗口顶部的距离
function posTop(obj){		
	var top = 0;
	while(obj){
		top += obj.offsetTop;
		obj = obj.offsetParent;
	}
	return top;
}

//获取视窗宽度高度
function getInner(){
	if(window.innerWidth){    	//高版本各浏览器 W3C标准
		return{
			width:window.innerWidth,  
			height:window.innerHeight
		}
	}else{
		return{          		//兼容低版本IE
			width:document.documentElement.clientWidth,  
			height:document.documentElement.clientHeight
		}
	}
} 

//ajax函数封装
function ajax(url, fnSucc, fnFaild)
{
	//1.创建Ajax对象
	var oAjax=null;
	
	if(window.XMLHttpRequest)
	{
		oAjax=new XMLHttpRequest();
	}
	else
	{
		oAjax=new ActiveXObject("Microsoft.XMLHTTP");
	}
	
	//2.连接服务器
	oAjax.open('GET', url, true);
	
	//3.发送请求
	oAjax.send();
	
	//4.接收服务器的返回
	oAjax.onreadystatechange=function ()
	{
		if(oAjax.readyState==4)		//请求完成
		{
			if(oAjax.status==200)	//完成且url页面存在
			{
				fnSucc(oAjax.responseText);
			}
			else
			{
				if(fnFaild)
				{
					fnFaild(oAjax.status);
				}
			}
		}
	};
}
</pre>

<p class="title">html代码</p>
<pre>
&ltdiv id="div1">
	&ltul>
		&ltli>
			&ltimg src="img/1.jpg" />
			&ltp>1111111111&lt/p>
		&lt/li>
		&ltli>
			&ltimg src="img/2.jpg" />
			&ltp>2222222222&lt/p>
		&lt/li>
		&ltli>
			&ltimg src="img/3.jpg" />
			&ltp>3333333333&lt/p>
		&lt/li>
	&lt/ul>
	&ltul>
		&ltli>
			&ltimg src="img/4.jpg" />
			&ltp>4444444444&lt/p>
		&lt/li>
		&ltli>
			&ltimg src="img/5.jpg" />
			&ltp>5555555555&lt/p>
		&lt/li>
		&ltli>
			&ltimg src="img/6.jpg" />
			&ltp>6666666666&lt/p>
		&lt/li>
		&ltli>
			&ltimg src="img/9.jpg" />
			&ltp>999999999&lt/p>
		&lt/li>
	&lt/ul>
	&ltul>
		&ltli>
			&ltimg src="img/7.jpg" />
			&ltp>777777777&lt/p>
		&lt/li>
		&ltli>
			&ltimg src="img/8.jpg" />
			&ltp>888888888&lt/p>
		&lt/li>
		&ltli>
			&ltimg src="img/9.jpg" />
			&ltp>000000000&lt/p>
		&lt/li>
	&lt/ul>
&lt/div>
</pre>

<p class="title">css代码</p>
<pre>
*{
	padding:0px;
	margin:0px;
}
ul{
	list-style: none;
}

#div1{
	width: 785px;
	height: auto;
	margin: 20px auto; 
}
ul{
	width: 225px;
	margin: 5px;
	float: left;
}
</pre>

<p class="title">php代码 demo.php模拟后台数据</p>
<pre>
//模拟后台数据
$dataArr = array();

for($i=1; $i<=10; $i++){
	$temp = "{
		batch: ".($i).",
		list: [
			{
				src: ['img/1.jpg', 'img/2.jpg', 'img/3.jpg'],
				title: ['新的第".($i)."批图片111', '新的第".($i)."批图片222', '新的第".($i)."批图片333']
			},
			{
				src: ['img/4.jpg', 'img/5.jpg', 'img/6.jpg', 'img/3.jpg'],
				title: ['新的第".($i)."批图片444', '新的第".($i)."批图片555', '新的第".($i)."批图片666', '新的第".($i)."批图片777']
			},
			{
				src: ['img/7.jpg', 'img/8.jpg', 'img/9.jpg'],
				title: ['新的第".($i)."批图片888', '新的第".($i)."批图片999', '新的第".($i)."批图片000']
			}
		]
	}";
	//形成10个json字符串 存入$dataArr数组中 
	array_push($dataArr, $temp);

	//根据不同的?xxxx 输出相应批次的数据
	if($_GET['batch'] == $i){
		echo $dataArr[$i-1];		//例如?batch=2就输出$dataArr[1] 也就是第二批数据
	}

}
</pre>


</body>
</html>